package com.yiyuan.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.guaike.core.entity.enums.EnableStatusEnum;
import com.guaike.core.entity.exception.ApiException;
import com.guaike.core.entity.result.Result;
import com.guaike.core.redis.context.ApiContext;
import com.guaike.core.utils.UUIDUtil;
import com.yiyuan.app.config.AliPayProperties;
import com.yiyuan.app.config.EnvironmentConfig;
import com.yiyuan.app.config.WxPayProperties;
import com.yiyuan.app.dao.*;
import com.yiyuan.app.entity.enums.*;
import com.yiyuan.app.entity.param.IosPayResultDTO;
import com.yiyuan.app.entity.param.RepayDTO;
import com.yiyuan.app.entity.param.UseEquityDTO;
import com.yiyuan.app.entity.po.*;
import com.yiyuan.app.entity.result.AppUser;
import com.yiyuan.app.entity.result.RepayVO;
import com.yiyuan.app.service.BaseDealPayService;
import com.yiyuan.app.service.BaseUtilService;
import com.yiyuan.app.service.PayService;
import com.yiyuan.app.utils.AppleVerifyUtils;
import com.wechat.pay.java.service.payments.app.AppServiceExtension;
import com.wechat.pay.java.service.payments.app.model.Amount;
import com.wechat.pay.java.service.payments.app.model.PrepayRequest;
import com.wechat.pay.java.service.payments.app.model.PrepayWithRequestPaymentResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service
@AllArgsConstructor
public class PayServiceImpl implements PayService {

    private final MProductLookDetailDAO mProductLookDetailDAO;
    private final MProductLookDAO mProductLookDAO;
    private final MProductOccupyDAO mProductOccupyDAO;
    private final BaseUtilService baseUtilService;
    private final MProductSeriesRechargeDAO mProductSeriesRechargeDAO;
    private final MRecordSeriesRechargeDAO mRecordSeriesRechargeDAO;
    private final MProductSeriesRechargeDaysDAO mProductSeriesRechargeDaysDAO;
    private final MRecordSeriesRechargeDetailDAO mRecordSeriesRechargeDetailDAO;
    private final DOrderRechargeDAO dOrderRechargeDAO;
    private final MProductPackageDAO mProductPackageDAO;
    private final MProductCardDAO mProductCardDAO;
    private final MProductCardDetailDAO mProductCardDetailDAO;
    private final UAppUserEquityDAO uAppUserEquityDAO;
    private final AlipayClient alipayClient;
    private final AliPayProperties aliPayProperties;
    private final AppServiceExtension appService;
    private final WxPayProperties properties;
    private final GConfDeviceDAO gConfDeviceDAO;
    private final GConfRoomDeviceDAO gConfRoomDeviceDAO;
    private final GRecordGameDAO gRecordGameDAO;
    private final GConfRoomDAO gConfRoomDAO;
    private final EnvironmentConfig environmentConfig;
    private final BaseDealPayService baseDealPayService;

    @Override
    @Transactional
    public Result<RepayVO> repayProduct(RepayDTO param) throws AlipayApiException {
        AppUser currentUser = ApiContext.getCurrentUser();
        DOrderRechargePO orderRechargePO = new DOrderRechargePO();
        orderRechargePO.setProductId(param.getId());
        orderRechargePO.setUserId(currentUser.getUserId());
        orderRechargePO.setProductType(param.getProductType());
        orderRechargePO.setPayType(param.getPayType());
        orderRechargePO.setStatus(OrderStatusEnum.pay_ready.getCode());
        orderRechargePO.setOrderNumber(UUIDUtil.createOrderNo());
        String iosProductId;
        if (OrderProductTypeEnum.lock_machine.getCode().equals(param.getProductType())) {
            GConfDevicePO devicePO = gConfDeviceDAO.findOne(GConfDevicePO::getSerialNumber, param.getSerialNumber());
            if (Objects.isNull(devicePO)) {
                return Result.failure().message("设备不存在").build();
            }
            if (Objects.nonNull(devicePO.getRepairTime())) {
                return Result.failure().message("设备维修中").build();
            }
            GConfRoomDevicePO roomDevicePO = gConfRoomDeviceDAO.findOne(GConfRoomDevicePO::getDeviceId, devicePO.getId());
            if (Objects.isNull(roomDevicePO)) {
                return Result.failure().message("设备未绑定房间").build();
            }
            GConfRoomPO roomPO = gConfRoomDAO.findById(roomDevicePO.getRoomId());
            if (Objects.isNull(roomPO) || roomPO.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
                return Result.failure().message("房间维护中").build();
            }
            GRecordGamePO gamePO = gRecordGameDAO.findUserPlaying(currentUser.getUserId(), roomDevicePO.getRoomId(), roomDevicePO.getPositionNo());
            if (Objects.isNull(gamePO)) {
                return Result.failure().message("您未在此机器游戏，不能锁机").build();
            }
            MProductLookDetailPO po = mProductLookDetailDAO.findById(param.getId());
            if (Objects.isNull(po)) {
                return Result.failure().message("商品不存在").build();
            }
            MProductLookPO lookPO = mProductLookDAO.findById(po.getLookId());
            if (Objects.isNull(lookPO) || lookPO.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
                return Result.failure().message("商品维护中").build();
            }
            if (!lookPO.getProductType().equals(EquityEnum.lock_machine.getCode())) {
                return Result.failure().message("商品类型不匹配").build();
            }
            orderRechargePO.setIosProductId(po.getAppleId().trim());
            orderRechargePO.setProductName("锁机" + po.getDuration() + "分钟");
            orderRechargePO.setOrderAmount(po.getMoney());
            Map<String, Object> productInfo = new HashMap<>();
            productInfo.put("gameRecordId", gamePO.getId());
            productInfo.put("duration", po.getDuration());
            orderRechargePO.setProductInfo(JSON.toJSONString(productInfo));
            iosProductId = po.getAppleId();
        } else if (OrderProductTypeEnum.forbid_look.getCode().equals(param.getProductType())) {
            GConfDevicePO devicePO = gConfDeviceDAO.findOne(GConfDevicePO::getSerialNumber, param.getSerialNumber());
            if (Objects.isNull(devicePO)) {
                return Result.failure().message("设备不存在").build();
            }
            if (Objects.nonNull(devicePO.getRepairTime())) {
                return Result.failure().message("设备维修中").build();
            }
            GConfRoomDevicePO roomDevicePO = gConfRoomDeviceDAO.findOne(GConfRoomDevicePO::getDeviceId, devicePO.getId());
            if (Objects.isNull(roomDevicePO)) {
                return Result.failure().message("设备未绑定房间").build();
            }
            GConfRoomPO roomPO = gConfRoomDAO.findById(roomDevicePO.getRoomId());
            if (Objects.isNull(roomPO) || roomPO.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
                return Result.failure().message("房间维护中").build();
            }
            if (!roomPO.getRoomType().equals(RoomTypeEnum.push_coins.getCode())) {
                return Result.failure().message("只有推币机房间可以禁止围观").build();
            }
            GRecordGamePO gamePO = gRecordGameDAO.findUserPlaying(currentUser.getUserId(), roomDevicePO.getRoomId(), roomDevicePO.getPositionNo());
            if (Objects.isNull(gamePO)) {
                return Result.failure().message("您未在此机器游戏，不能禁止围观").build();
            }
            MProductLookDetailPO po = mProductLookDetailDAO.findById(param.getId());
            if (Objects.isNull(po)) {
                return Result.failure().message("商品不存在").build();
            }
            MProductLookPO lookPO = mProductLookDAO.findById(po.getLookId());
            if (Objects.isNull(lookPO) || lookPO.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
                return Result.failure().message("商品维护中").build();
            }
            if (!lookPO.getProductType().equals(EquityEnum.forbid_look.getCode())) {
                return Result.failure().message("商品类型不匹配").build();
            }
            orderRechargePO.setIosProductId(po.getAppleId().trim());
            orderRechargePO.setProductName("禁止围观" + po.getDuration() + "分钟");
            orderRechargePO.setOrderAmount(po.getMoney());
            Map<String, Object> productInfo = new HashMap<>();
            productInfo.put("gameRecordId", gamePO.getId());
            productInfo.put("duration", po.getDuration());
            orderRechargePO.setProductInfo(JSON.toJSONString(productInfo));
            iosProductId = po.getAppleId();
        } else if (OrderProductTypeEnum.occupy.getCode().equals(param.getProductType())) {
            GConfDevicePO devicePO = gConfDeviceDAO.findOne(GConfDevicePO::getSerialNumber, param.getSerialNumber());
            if (Objects.isNull(devicePO)) {
                return Result.failure().message("设备不存在").build();
            }
            if (Objects.nonNull(devicePO.getRepairTime())) {
                return Result.failure().message("设备维修中").build();
            }
            GConfRoomDevicePO roomDevicePO = gConfRoomDeviceDAO.findOne(GConfRoomDevicePO::getDeviceId, devicePO.getId());
            if (Objects.isNull(roomDevicePO)) {
                return Result.failure().message("设备未绑定房间").build();
            }
            GConfRoomPO roomPO = gConfRoomDAO.findById(roomDevicePO.getRoomId());
            if (Objects.isNull(roomPO) || roomPO.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
                return Result.failure().message("房间维护中").build();
            }
            GRecordGamePO gamePO = gRecordGameDAO.findUserPlaying(currentUser.getUserId(), roomDevicePO.getRoomId(), roomDevicePO.getPositionNo());
            if (Objects.isNull(gamePO)) {
                return Result.failure().message("您未在此机器游戏，不能包机").build();
            }
            MProductOccupyPO po = mProductOccupyDAO.findById(param.getId());
            if (Objects.isNull(po)) {
                return Result.failure().message("商品不存在").build();
            }
            if (po.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
                return Result.failure().message("商品维护中").build();
            }
            orderRechargePO.setIosProductId(po.getAppleId().trim());
            orderRechargePO.setProductName(po.getProductName());
            orderRechargePO.setOrderAmount(po.getMoney());
            Map<String, Object> productInfo = new HashMap<>();
            productInfo.put("gameRecordId", gamePO.getId());
            productInfo.put("duration", po.getDuration());
            productInfo.put("pinecone", po.getPinecone());
            orderRechargePO.setProductInfo(JSON.toJSONString(productInfo));
            iosProductId = po.getAppleId();
        } else if (OrderProductTypeEnum.series_recharge.getCode().equals(param.getProductType())) {
            if (Objects.isNull(param.getId())) {
                return Result.failure().message("今日已经续航过了，请勿重复续航").build();
            }
            MProductSeriesRechargeDaysPO po = mProductSeriesRechargeDaysDAO.findById(param.getId());
            if (Objects.isNull(po)) {
                return Result.failure().message("商品不存在").build();
            }
            MProductSeriesRechargePO rechargePO = mProductSeriesRechargeDAO.findById(po.getRechargeId());
            if (Objects.isNull(rechargePO) || rechargePO.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
                return Result.failure().message("商品维护中").build();
            }
            MRecordSeriesRechargePO latestOne = mRecordSeriesRechargeDAO.findLatestOne(currentUser.getUserId());
            if (Objects.nonNull(latestOne)) {
                MRecordSeriesRechargeDetailPO detailPO = mRecordSeriesRechargeDetailDAO.findAlreadyRecharge(currentUser.getUserId(), latestOne.getId(), po.getSeriesDays());
                if (Objects.nonNull(detailPO) && detailPO.getCreateTime().toLocalDate().isEqual(LocalDate.now())) {
                    return Result.failure().message("今日已经续航过了，请勿重复续航").build();
                }
                Boolean seriesRecharge = baseUtilService.checkSeriesRecharge(currentUser.getUserId(), po.getSeriesDays(), latestOne);
                if (!seriesRecharge) {
                    return Result.failure().message("只能连续续航").build();
                }
            } else {
                if (po.getSeriesDays() != 1) {
                    return Result.failure().message("只能连续续航").build();
                }
            }
            orderRechargePO.setIosProductId(po.getAppleId().trim());
            orderRechargePO.setProductName("每日续航第" + po.getSeriesDays() + "天");
            orderRechargePO.setOrderAmount(po.getMoney());
            Map<String, Object> productInfo = new HashMap<>();
            productInfo.put("seriesDays", po.getSeriesDays());
            if (po.getSeriesDays() != 1) {
                productInfo.put("recordRechargeId", latestOne.getId());
            }
            productInfo.put("seriesDays", po.getSeriesDays());
            productInfo.put("pinecone", po.getPinecone());
            orderRechargePO.setProductInfo(JSON.toJSONString(productInfo));
            iosProductId = po.getAppleId();
        } else if (OrderProductTypeEnum.novice_gift_pack.getCode().equals(param.getProductType())) {
            MProductPackagePO po = mProductPackageDAO.findById(param.getId());
            if (Objects.isNull(po)) {
                return Result.failure().message("商品不存在").build();
            }
            if (!po.getProductType().equals(PackageTypeEnum.new_person_package.getCode())) {
                return Result.failure().message("商品类型不匹配").build();
            }
            if (po.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
                return Result.failure().message("商品维护中").build();
            }
            DOrderRechargePO rechargePO = dOrderRechargeDAO.findNoviceGiftPack(currentUser.getUserId(), OrderStatusEnum.pay_success.getCode());
            if (Objects.nonNull(rechargePO)) {
                return Result.failure().message("你已经购买过，请勿重复购买").build();
            }
            DOrderRechargePO readyPO = dOrderRechargeDAO.findNoviceGiftPack(currentUser.getUserId(), OrderStatusEnum.pay_ready.getCode());
            if (Objects.nonNull(readyPO)) {
                readyPO.setStatus(OrderStatusEnum.pay_fail.getCode());
                dOrderRechargeDAO.updateById(readyPO);
            }
            orderRechargePO.setIosProductId(po.getAppleId().trim());
            orderRechargePO.setProductName(po.getProductName());
            orderRechargePO.setOrderAmount(po.getMoney());
            Map<String, Object> productInfo = new HashMap<>();
            productInfo.put("pinecone", po.getPinecone());
            orderRechargePO.setProductInfo(JSON.toJSONString(productInfo));
            iosProductId = po.getAppleId();
        } else if (OrderProductTypeEnum.activity_pack.getCode().equals(param.getProductType())) {
            MProductPackagePO po = mProductPackageDAO.findById(param.getId());
            if (Objects.isNull(po)) {
                return Result.failure().message("商品不存在").build();
            }
            if (!po.getProductType().equals(PackageTypeEnum.activity_package.getCode())) {
                return Result.failure().message("商品类型不匹配").build();
            }
            if (po.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
                return Result.failure().message("商品维护中").build();
            }
            orderRechargePO.setIosProductId(po.getAppleId().trim());
            orderRechargePO.setProductName(po.getProductName());
            orderRechargePO.setOrderAmount(po.getMoney());
            Map<String, Object> productInfo = new HashMap<>();
            productInfo.put("pinecone", po.getPinecone());
            orderRechargePO.setProductInfo(JSON.toJSONString(productInfo));
            iosProductId = po.getAppleId();
        } else if (OrderProductTypeEnum.recharge_activity.getCode().equals(param.getProductType())) {
            MProductPackagePO po = mProductPackageDAO.findById(param.getId());
            if (Objects.isNull(po)) {
                return Result.failure().message("商品不存在").build();
            }
            if (!po.getProductType().equals(PackageTypeEnum.recharge_activity.getCode())) {
                return Result.failure().message("商品类型不匹配").build();
            }
            if (po.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
                return Result.failure().message("商品维护中").build();
            }
            orderRechargePO.setIosProductId(po.getAppleId().trim());
            orderRechargePO.setProductName(po.getProductName());
            orderRechargePO.setOrderAmount(po.getMoney());
            Map<String, Object> productInfo = new HashMap<>();
            productInfo.put("pinecone", po.getPinecone());
            orderRechargePO.setProductInfo(JSON.toJSONString(productInfo));
            iosProductId = po.getAppleId();
        } else if (OrderProductTypeEnum.month_card.getCode().equals(param.getProductType())) {
            MProductCardDetailPO po = mProductCardDetailDAO.findById(param.getId());
            if (Objects.isNull(po)) {
                return Result.failure().message("商品不存在").build();
            }
            if (!po.getCardType().equals(CardTypeEnum.month_card.getCode())) {
                return Result.failure().message("商品类型不匹配").build();
            }
            MProductCardPO cardPO = mProductCardDAO.findById(po.getProductCardId());
            if (Objects.isNull(cardPO) || cardPO.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
                return Result.failure().message("商品维护中").build();
            }
            orderRechargePO.setIosProductId(po.getAppleId().trim());
            orderRechargePO.setProductName(po.getCardName());
            orderRechargePO.setOrderAmount(po.getMoney());
            Map<String, Object> productInfo = new HashMap<>();
            productInfo.put("directlyPinecone", po.getDirectlyPinecone());
            productInfo.put("dailyPinecone", po.getDailyPinecone());
            productInfo.put("days", 30);
            orderRechargePO.setProductInfo(JSON.toJSONString(productInfo));
            iosProductId = po.getAppleId();
        } else if (OrderProductTypeEnum.week_card.getCode().equals(param.getProductType())) {
            MProductCardDetailPO po = mProductCardDetailDAO.findById(param.getId());
            if (Objects.isNull(po)) {
                return Result.failure().message("商品不存在").build();
            }
            if (!po.getCardType().equals(CardTypeEnum.week_card.getCode())) {
                return Result.failure().message("商品类型不匹配").build();
            }
            MProductCardPO cardPO = mProductCardDAO.findById(po.getProductCardId());
            if (Objects.isNull(cardPO) || cardPO.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
                return Result.failure().message("商品维护中").build();
            }
            orderRechargePO.setIosProductId(po.getAppleId().trim());
            orderRechargePO.setProductName(po.getCardName());
            orderRechargePO.setOrderAmount(po.getMoney());
            Map<String, Object> productInfo = new HashMap<>();
            productInfo.put("directlyPinecone", po.getDirectlyPinecone());
            productInfo.put("dailyPinecone", po.getDailyPinecone());
            productInfo.put("days", 7);
            orderRechargePO.setProductInfo(JSON.toJSONString(productInfo));
            iosProductId = po.getAppleId();
        } else {
            return Result.failure().message("商品类型不正确").build();
        }
        dOrderRechargeDAO.save(orderRechargePO);
        RepayVO vo = new RepayVO();
        vo.setOrderId(orderRechargePO.getId());
        if (param.getPayType().equals(PayTypeEnum.ali.getCode())) {
            AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            model.setSubject(orderRechargePO.getProductName());
            model.setOutTradeNo(orderRechargePO.getOrderNumber());
            model.setTotalAmount(orderRechargePO.getOrderAmount().toPlainString());
            request.setBizModel(model);
            request.setNotifyUrl(aliPayProperties.getCallBackUrl());
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            if (!response.isSuccess()) {
                throw new ApiException(response.getMsg());
            }
            vo.setPrepayId(response.getBody());
        } else if (param.getPayType().equals(PayTypeEnum.wx.getCode())) {
            PrepayRequest request = new PrepayRequest();
            Amount amount = new Amount();
            amount.setTotal(orderRechargePO.getOrderAmount().multiply(new BigDecimal(100)).intValue());
            request.setAmount(amount);
            request.setAppid(properties.getAppId());
            request.setMchid(properties.getMerchantId());
            request.setDescription(orderRechargePO.getProductName());
            request.setNotifyUrl(properties.getCallBackUrl());
            request.setOutTradeNo(orderRechargePO.getOrderNumber());
            PrepayWithRequestPaymentResponse response = appService.prepayWithRequestPayment(request);
            vo.setPrepayId(JSON.toJSONString(response));
        } else if (param.getPayType().equals(PayTypeEnum.ios.getCode())) {
            vo.setPrepayId(iosProductId.trim());
        } else {
            return Result.failure().message("支付类型不正确").build();
        }
        return Result.success().data(vo).build();
    }

    @Override
    @Transactional
    public Result<Boolean> useEquity(UseEquityDTO param) throws IOException, InterruptedException {
        AppUser currentUser = ApiContext.getCurrentUser();
        UAppUserEquityPO equityPO = uAppUserEquityDAO.findByUserIdLock(currentUser.getUserId());
        if (OrderProductTypeEnum.lock_machine.getCode().equals(param.getProductType())) {
            GConfDevicePO devicePO = gConfDeviceDAO.findOne(GConfDevicePO::getSerialNumber, param.getSerialNumber());
            if (Objects.isNull(devicePO)) {
                return Result.failure().message("设备不存在").build();
            }
            if (Objects.nonNull(devicePO.getRepairTime())) {
                return Result.failure().message("设备维修中").build();
            }
            GConfRoomDevicePO roomDevicePO = gConfRoomDeviceDAO.findOne(GConfRoomDevicePO::getDeviceId, devicePO.getId());
            if (Objects.isNull(roomDevicePO)) {
                return Result.failure().message("设备未绑定房间").build();
            }
            GConfRoomPO roomPO = gConfRoomDAO.findById(roomDevicePO.getRoomId());
            if (Objects.isNull(roomPO) || roomPO.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
                return Result.failure().message("房间维护中").build();
            }
            GRecordGamePO gamePO = gRecordGameDAO.findUserPlaying(currentUser.getUserId(), roomDevicePO.getRoomId(), roomDevicePO.getPositionNo());
            if (Objects.isNull(gamePO)) {
                return Result.failure().message("您未在此机器游戏，不能锁机").build();
            }
            MProductLookDetailPO po = mProductLookDetailDAO.findById(param.getId());
            if (Objects.isNull(po)) {
                return Result.failure().message("商品不存在").build();
            }
            MProductLookPO lookPO = mProductLookDAO.findById(po.getLookId());
            if (!lookPO.getProductType().equals(EquityEnum.lock_machine.getCode())) {
                return Result.failure().message("商品类型不匹配").build();
            }
            if (po.getDuration().equals(15) && equityPO.getLockFifteen() <= 0) {
                return Result.failure().message("权益值不足，请购买").build();
            }
            if (po.getDuration().equals(30) && equityPO.getLockThirty() <= 0) {
                return Result.failure().message("权益值不足，请购买").build();
            }
            if (po.getDuration().equals(60) && equityPO.getLockSixty() <= 0) {
                return Result.failure().message("权益值不足，请购买").build();
            }
            String checkGaming = gamePO.getRoomId() + gamePO.getPositionNo();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("duration", po.getDuration());
            Boolean aBoolean = baseUtilService.checkGaming(checkGaming, currentUser.getUserId(), gamePO.getRoomId(), gamePO.getPositionNo(), OrderProductTypeEnum.lock_machine.getCode(), jsonObject);
            if (!aBoolean) {
                return Result.failure().message("权益使用失败").build();
            }
            if (po.getDuration().equals(15)) {
                equityPO.setLockFifteen(equityPO.getLockFifteen() - 1);
            } else if (po.getDuration().equals(30)) {
                equityPO.setLockThirty(equityPO.getLockThirty() - 1);
            } else if (po.getDuration().equals(60)) {
                equityPO.setLockSixty(equityPO.getLockSixty() - 1);
            }
        } else if (OrderProductTypeEnum.forbid_look.getCode().equals(param.getProductType())) {
            if (equityPO.getForbidLookThirty() <= 0) {
                return Result.failure().message("权益值不足，请购买").build();
            }
            GConfDevicePO devicePO = gConfDeviceDAO.findOne(GConfDevicePO::getSerialNumber, param.getSerialNumber());
            if (Objects.isNull(devicePO)) {
                return Result.failure().message("设备不存在").build();
            }
            if (Objects.nonNull(devicePO.getRepairTime())) {
                return Result.failure().message("设备维修中").build();
            }
            GConfRoomDevicePO roomDevicePO = gConfRoomDeviceDAO.findOne(GConfRoomDevicePO::getDeviceId, devicePO.getId());
            if (Objects.isNull(roomDevicePO)) {
                return Result.failure().message("设备未绑定房间").build();
            }
            GConfRoomPO roomPO = gConfRoomDAO.findById(roomDevicePO.getRoomId());
            if (Objects.isNull(roomPO) || roomPO.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
                return Result.failure().message("房间维护中").build();
            }
            if (!roomPO.getRoomType().equals(RoomTypeEnum.push_coins.getCode())) {
                return Result.failure().message("只有推币机房间可以禁止围观").build();
            }
            GRecordGamePO gamePO = gRecordGameDAO.findUserPlaying(currentUser.getUserId(), roomDevicePO.getRoomId(), roomDevicePO.getPositionNo());
            if (Objects.isNull(gamePO)) {
                return Result.failure().message("您未在此机器游戏，不能禁止围观").build();
            }
            MProductLookDetailPO po = mProductLookDetailDAO.findById(param.getId());
            if (Objects.isNull(po)) {
                return Result.failure().message("商品不存在").build();
            }
            MProductLookPO lookPO = mProductLookDAO.findById(po.getLookId());
            if (!lookPO.getProductType().equals(EquityEnum.forbid_look.getCode())) {
                return Result.failure().message("商品类型不匹配").build();
            }
            String checkGaming = gamePO.getRoomId() + gamePO.getPositionNo();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("duration", po.getDuration());
            Boolean aBoolean = baseUtilService.checkGaming(checkGaming, currentUser.getUserId(), gamePO.getRoomId(), gamePO.getPositionNo(), OrderProductTypeEnum.forbid_look.getCode(), jsonObject);
            if (!aBoolean) {
                return Result.failure().message("权益使用失败").build();
            }
            equityPO.setForbidLookThirty(equityPO.getForbidLookThirty() - 1);
        }
        uAppUserEquityDAO.updateById(equityPO);
        return Result.success().data(Boolean.TRUE).build();
    }

    @Override
    public Result<Boolean> dealIosPayResult(IosPayResultDTO param) throws Exception {
        AppUser currentUser = ApiContext.getCurrentUser();
        DOrderRechargePO orderPO = dOrderRechargeDAO.findById(param.getOrderId());
        if (Objects.isNull(orderPO)) {
            return Result.failure().message("订单不存在").build();
        }
        if (!currentUser.getUserId().equals(orderPO.getUserId())) {
            return Result.failure().message("该订单不是你的").build();
        }
        if (orderPO.getStatus().equals(OrderStatusEnum.pay_ready.getCode())) {
            int type;
            log.info("dealIosPayResult>>>>active: {},", environmentConfig.getActive());
            log.info("dealIosPayResult>>>>equals: {},", "online".equalsIgnoreCase(environmentConfig.getActive()));
            if ("online".equalsIgnoreCase(environmentConfig.getActive())) {
                type = 1;
            } else {
                type = 0;
            }
            String receipt = param.getReceipt();
            // 注意，有的票据在客户端接收时 加号 可能会被转换为 空格
            String data = receipt.replace(" ", "+");
            // 请求苹果服务器进行票据验证
            String result = AppleVerifyUtils.verifyApple(data, type);
            log.info("[AppleVerifyUtils result] {}", result);
            if (null == result) {
                log.error("[ verify receipt error]");
                return Result.failure().message("解析票据异常").build();
            }

            JSONObject receiptData = JSONObject.parseObject(result);
            int status = receiptData.getInteger("status");
            // 苹果生成的订单号
            String transactionId;
            // 购买时间，单位：毫秒
            Long purchaseDateMs;
            // 商品ID 与在APP Store 后台配置的一致
            String productId;
            JSONObject receiptInfo = receiptData.getJSONObject("receipt");
            if (receiptInfo == null) {
                return Result.failure().message("票据信息为空").build();
            }
            log.info("[ receiptInfo result] {}", receiptInfo.toJSONString());
            JSONArray inAppList = receiptInfo.getJSONArray("in_app");
            if (CollectionUtils.isNotEmpty(inAppList)) {
                // ios7之前的数据格式
                inAppList.sort(Comparator.comparingLong(json -> ((JSONObject) json).getLong("purchase_date_ms")).reversed());
                JSONObject inApp = inAppList.getJSONObject(0);
                transactionId = inApp.getString("transaction_id");
                purchaseDateMs = inApp.getLong("purchase_date_ms");
                productId = inApp.getString("product_id");
            } else {
                // ios7之后的数据格式
                transactionId = receiptInfo.getString("transaction_id");
                purchaseDateMs = receiptInfo.getLong("purchase_date_ms");
                productId = receiptInfo.getString("product_id");
            }
            // 判断product_id，看返回的product_id与实际的充值金额是不是一致，防止骗单
            if (!productId.equals(orderPO.getIosProductId())) {
                return Result.failure().message("商品对应错误").build();
            }
            orderPO.setOutTradeNo(transactionId);
            if (0 == status) {
                orderPO.setStatus(OrderStatusEnum.pay_success.getCode());
                orderPO.setPayAmount(orderPO.getOrderAmount());
                orderPO.setPayTime(LocalDateTime.ofEpochSecond(purchaseDateMs / 1000, 0, ZoneOffset.UTC).atZone(ZoneId.of("UTC")).withZoneSameInstant(ZoneId.of("Asia/Shanghai")).toLocalDateTime());
            } else {
                orderPO.setStatus(OrderStatusEnum.pay_fail.getCode());
                log.info("[ ios pay fail ] status:{}", status);
            }
            dOrderRechargeDAO.updateById(orderPO);
            baseDealPayService.dealOrder(orderPO);
        }
        return Result.success().data(Boolean.TRUE).build();
    }
}
